package cn.net.susan.service.sys;


import cn.hutool.core.util.IdUtil;
import cn.net.susan.entity.ResponsePageEntity;
import cn.net.susan.entity.sys.*;
import cn.net.susan.entity.user.CaptchaEntity;
import cn.net.susan.exception.BusinessException;
import cn.net.susan.hleper.TokenHelper;
import cn.net.susan.mapper.sys.UserMapper;
import cn.net.susan.service.impl.UserDetailsServiceImpl;
import cn.net.susan.util.AssertUtil;
import cn.net.susan.util.PasswordUtil;
import cn.net.susan.util.RedisUtil;
import cn.net.susan.util.TokenUtil;
import com.wf.captcha.ArithmeticCaptcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 用户 服务层
 * 
 * @author 苏三 该项目是知识星球：java突击队 的内部项目
 * @date 2024-01-08 14:03:43
 */
@Service
@Slf4j
public class UserService {

	@Autowired
	private UserMapper userMapper;

	@Autowired
	private PasswordUtil passwordUtil;

	@Autowired
	private TokenHelper tokenHelper;

	@Autowired
	private AuthenticationManagerBuilder authenticationManagerBuilder;

	@Autowired
	private RedisUtil redisUtil;

	@Autowired
	private UserDetailsServiceImpl userDetailsService;
	private static final String CAPTCHA_PREFIX = "captcha:";
	/**
	 * 设置验证码过期时间为 60
	 */
	@Value("${mall.mgt.captchaExpireSecond:60}")
	private int captchaExpireSecond;

	/**
	 * 用户登录
	 * @param authUserEntity 用户录入信息
	 */

	public TokenEntity login(AuthUserEntity authUserEntity) {
		String code = redisUtil.get(getCaptchaKey(authUserEntity.getUuid()));
		AssertUtil.hasLength(code, "该验证码不存在或者已失效");
		AssertUtil.isTrue(code.trim().equals(authUserEntity.getCode().trim()), "验证码错误");
		redisUtil.del(getCaptchaKey(authUserEntity.getUuid()));
		try {
			String decodePassword = passwordUtil.decodeRsaPassword(authUserEntity);
			UsernamePasswordAuthenticationToken authenticationToken =
					new UsernamePasswordAuthenticationToken(authUserEntity.getUsername(), decodePassword);
			Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
			SecurityContextHolder.getContext().setAuthentication(authentication);
			String token = tokenHelper.generateToken((JwtUserEntity) (authentication.getPrincipal()));
			return new TokenEntity(authUserEntity.getUsername(), token);
		} catch (Exception e) {
			log.info("登录失败：", e);
			throw new BusinessException(HttpStatus.FORBIDDEN.value(), " 用户名或密码错误");
		}
	}

	/**
	 * 用户登出
	 * @param request
	 */
	public void loginout(HttpServletRequest request){
		String token= TokenUtil.getTokenForAuthorization(request);
		AssertUtil.hasLength(token,"Authorization不正确");
		tokenHelper.delToken(token);
	}

	public JwtUserEntity getUserInfo(){
		String currentUsername=tokenHelper.getcurrentUsername();
		return (JwtUserEntity) userDetailsService.loadUserByUsername(currentUsername);
	}

	/**
     * 查询用户信息
     * 
     * @param id 用户ID
     * @return 用户信息
     */
	public UserEntity findById(Long id) {
	    return userMapper.findById(id);
	}
	
	/**
     * 根据条件分页查询用户列表
     * 
     * @param userConditionEntity 用户信息
     * @return 用户集合
     */
	public ResponsePageEntity<UserEntity> searchByPage(UserConditionEntity userConditionEntity) {
		int count = userMapper.searchCount(userConditionEntity);
		if (count == 0) {
			return ResponsePageEntity.buildEmpty(userConditionEntity);
		}
		List<UserEntity> dataList = userMapper.searchByCondition(userConditionEntity);
		return ResponsePageEntity.build(userConditionEntity, count, dataList);
	}
	
    /**
     * 新增用户
     * 
     * @param userEntity 用户信息
     * @return 结果
     */
	public int insert(UserEntity userEntity) {
	    return userMapper.insert(userEntity);
	}
	
	/**
     * 修改用户
     * 
     * @param userEntity 用户信息
     * @return 结果
     */
	public int update(UserEntity userEntity) {
	    return userMapper.update(userEntity);
	}

	/**
     * 删除用户对象
     * 
     * @param id 系统ID
     * @return 结果
     */
	public int deleteById(Long id) {
		return userMapper.deleteById(id);
	}

	/**
	 * 增加获取验证码接口
	 * @return
	 */
	public CaptchaEntity getCode() {
		//创建运算验证码对象，说明生成掩证码图片的像素的高度与宽度
		ArithmeticCaptcha captcha = new ArithmeticCaptcha(111, 36);
		// 设置运算位数，默认是两位
		captcha.setLen(2);
		// 获取正确的运算结果
		String result = "";
		try {
			//将结果转换为int类型
			result = new Double(Double.parseDouble(captcha.text())).intValue() + "";
		} catch (Exception e) {
			result = captcha.text();
		}
		//生成验证码唯一的uuid
		String uuid = "C" + IdUtil.simpleUUID();
		// 保存验证码到Redis中
		redisUtil.set(getCaptchaKey(uuid), result, captchaExpireSecond);
		//返回封装结果
		return new CaptchaEntity(uuid, captcha.toBase64());
	}

	private String getCaptchaKey(String uuid) {
		return String.format("%s%s", CAPTCHA_PREFIX, uuid);
	}
	
}
